/**
 * 	 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *   @author Colin Redmond
 *   Copyright (C) 2011 Colin Redmond
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

package com.cred.industries.core.database;

import java.sql.Connection;
import java.sql.SQLException;

import org.apache.tomcat.jdbc.pool.PoolProperties;
import org.apache.tomcat.jdbc.pool.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * uses org.apache.commons.dbcp to create a Db connection pool
 * to use across the program.
 */
public final class DBConnectionManager {

	private static final Logger logger = LoggerFactory.getLogger(DBConnectionManager.class);
	
	private static final DBConnectionManager sInstance = new DBConnectionManager();
	private DataSource mDataSource;
		
	/**
	 * returns the singleton connection manager or creates and returns one if
	 * it does not exist. 
	 * @return singleton instance of DBConnectionManager
	 */
	public static DBConnectionManager getInstance() {
		
		return sInstance;
	}
	
	/**
	 * creates the DBConnectionManager
	 */
	private DBConnectionManager() {
		
		DBConfig dbConfig = new DBConfig();		
		createDataSources(dbConfig.getDBDriverName(), 
				dbConfig.getDBURI(), 
				dbConfig.getDBUserName(), 
				dbConfig.getDBPassword(),
				dbConfig.getDBPoolMinCon(), 
				dbConfig.getDBPoolMaxCon());
	}
	
	/**
	 * Creates the db connection pool
	 * @param driverName name of the SQL driver
	 * @param uri path to connect to the SQl DB
	 * @param dbUserName user name to connect to the DB with
	 * @param dbPassword password for the user name to connect to the DB
	 * @param minCon min number of connections to keep alive with DB
	 * @param maxConn maximum number of connections to make with the DB
	 */
	private void createDataSources(String driverName, String uri, String dbUserName, String dbPassword, int minCon, int maxConn) {
		
		PoolProperties p = new PoolProperties();
        p.setUrl(uri);
        p.setDriverClassName(driverName);
        p.setUsername(dbUserName);
        p.setPassword(dbPassword);
        p.setJmxEnabled(true);
        p.setTestWhileIdle(false);
        p.setTestOnBorrow(true);
        p.setValidationQuery("SELECT 1");
        p.setTestOnReturn(false);
        p.setValidationInterval(30000);
        p.setTimeBetweenEvictionRunsMillis(30000);
        p.setMaxActive(maxConn);
        p.setInitialSize(10);
        p.setMaxWait(10000);
        p.setRemoveAbandonedTimeout(60);
        p.setMinEvictableIdleTimeMillis(30000);
        p.setMinIdle(minCon);
        p.setLogAbandoned(true);
        p.setRemoveAbandoned(true);
        p.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+
          "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
        DataSource datasource = new DataSource();
        datasource.setPoolProperties(p); 
		
		//set the local data
		mDataSource = datasource;
	}

	/**
	 * gets the data source for the connection manager
	 * @return the data source for the connection manager
	 */
	public DataSource getDataSource() {
		return mDataSource;
	}
	
	/**
	 * gets a connection from the pool
	 * @return gets a connection from the pool
	 * @throws SQLException
	 */
	public Connection getConnection() throws SQLException {
		return mDataSource.getConnection();
	}
}
